package com.dacd.soundanalysis.thread

import android.content.Context
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.Handler
import android.util.Log
import com.alibaba.fastjson.JSON
import com.dacd.soundanalysis.bean.SoundBean
import com.dacd.soundanalysis.filehelper.FileConstants
import com.dacd.soundanalysis.filehelper.FileHelper
import com.dacd.soundanalysis.soundhelper.FrequencyScanner
import com.dacd.soundanalysis.soundhelper.SoundConstants
import java.io.File
import kotlin.math.sqrt
import kotlin.random.Random

class ListenThread(context: Context, handler:Handler) : Thread() {

    private var audioRecord: AudioRecord? = null//录音类
    private var minBufferSize: Int = 0
    private var isRecording = false
    private var compareList: List<SoundBean>? = null
    private var currentVolume: Double = 0.0
    private var currentFrequency: Double = 0.0
    private var context: Context? = null
    private var isComparing: Boolean = false//是否正在对比状态中
    private var recordList: ArrayList<SoundBean>? = null
    private var startTime: Long = 0 //开始分析录制的时间
    private var durationTime: Long = 0//之前记录的持续时间
    private var handler:Handler? = null

    init {
        this.context = context
        this.handler = handler
    }

    fun initAudioLearnThread(): Boolean {
        //检查是否有需要识别的文件
        val recordDir = File(context!!.cacheDir.absolutePath + FileConstants.RECORD_FILE_DIR)
        if (!recordDir.exists()) {
            return false
        }
        val recordFiles =
            File(context!!.cacheDir.absolutePath + FileConstants.RECORD_FILE_DIR, "record")
        compareList =
            JSON.parseArray(File(recordFiles.absolutePath).readText(), SoundBean::class.java)
        if (compareList == null || compareList!!.size < 2) {
            return false
        }
        durationTime =
            compareList!![compareList!!.size - 1].timeMillis
        if (!recordFiles.exists()) {
            return false
        }
        minBufferSize = AudioRecord.getMinBufferSize(
            SoundConstants.SAMPLE_RATE,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT
        )
        audioRecord = AudioRecord(
            MediaRecorder.AudioSource.MIC,
            SoundConstants.SAMPLE_RATE
            ,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT
            , minBufferSize
        )
        minBufferSize = 1024
        if (AudioRecord.ERROR_BAD_VALUE == minBufferSize || AudioRecord.ERROR == minBufferSize) {
            //设备不支持
            return false
        }
        if (audioRecord!!.state != AudioRecord.STATE_INITIALIZED) {
            return false
        }
        return true
    }

    override fun run() {
        //开始录音
        isRecording = true
        val bufferRead = ShortArray(minBufferSize)
        audioRecord!!.startRecording()
        while (isRecording && audioRecord!!.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
            var sum: Double = 0.0
            val readSize = audioRecord!!.read(bufferRead, 0, minBufferSize)
            for (i in 0 until readSize) {
                sum += bufferRead[i] * bufferRead[i]
            }
            if (readSize > 0) {
                val amplitude: Double = sum / readSize
                currentVolume = sqrt(amplitude)
            }
            if (currentVolume > SoundConstants.VOLUME_LIMIT && !isComparing) {//声音大于1000后开始频率对比
                recordList = ArrayList()
                currentFrequency =
                    FrequencyScanner().extractFrequency(
                        bufferRead,
                        SoundConstants.SAMPLE_RATE
                    )//获取到了当前的频率
                var isCompareStart = false
                for (i in 0 until 5) {
                    if ((kotlin.math.abs(compareList!![i].frequency - currentFrequency.toInt()) < SoundConstants.SOUND_START_FRE_COMPARE)) {//如果有匹配的
                        isCompareStart = true
                        break
                    }
                }
                if (isCompareStart) {//如果有匹配的
                    handler!!.sendEmptyMessage(2)
                    isComparing = true
                    val soundBean = SoundBean()
                    startTime = System.currentTimeMillis()
                    soundBean.timeMillis = startTime
                    soundBean.frequency = currentFrequency.toInt()
                    recordList!!.add(soundBean)
                }
            } else if (isComparing) {//配对中的状态
                val nowMilli = System.currentTimeMillis()
                if ((nowMilli - startTime) > durationTime) {//已经超出了录制时间
                    isComparing = false//停止录制
                    val random = Random.nextLong(500, 4000)
                    Thread.sleep(random)
                    if (recordList!!.size > 20) {//如果有多条数据，进行匹配
                        val record = JSON.toJSON(recordList).toString()
                        val fileName = "record2"
                        FileHelper.saveFile(context!!.cacheDir.absolutePath + FileConstants.RECORD_FILE_DIR,
                            fileName, record)
                        AnalysisThread(handler!!, compareList!!, recordList!!).start()
                    }
                } else if (currentVolume > SoundConstants.VOLUME_LIMIT) {//对声音大于1000的进行收录
                    currentFrequency = FrequencyScanner().extractFrequency(
                        bufferRead,
                        SoundConstants.SAMPLE_RATE
                    )//获取到了当前的频率
                    val soundBean = SoundBean()
                    soundBean.timeMillis = nowMilli - recordList!![0].timeMillis
                    soundBean.frequency = currentFrequency.toInt()
                    Log.e("listen", currentFrequency.toString())
                    recordList!!.add(soundBean)
                }
            }
        }
    }

    /**
     * 停止录音
     */
    fun stopRecord() {
        isRecording = false
        isComparing = false//停止录制
        if (audioRecord != null) {
            if (audioRecord!!.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功
                audioRecord!!.stop();
            }
            if (audioRecord != null) {
                audioRecord!!.release();
            }
        }
    }
}